package com.aysafety.iotdataplatformweb.services.soundemission.impl;

import com.aysafety.core.DBDriver.hbase.HBaseDriver;
import com.aysafety.core.common.DateUtils;
import com.aysafety.iotdataplatformweb.dao.SoundDao;
import com.aysafety.iotdataplatformweb.services.soundemission.SoundEmissionService;
import com.safety.algorithm.eigenvalue.EigenvalueAlgorithm;
import com.safety.algorithm.eigenvalue.soundEmission.SoundEmissionAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service public class SoundEmissionServiceImpl implements SoundEmissionService {

    private final Map<String, Object> calMap = new HashMap<String, Object>() {
        {
            put("entId", "String");
            put("workingFace", "String");
            put("calType", "Integer");
            put("electromagneticWarningIndicator", "Double");
            put("hoursDeviation", "Double");
            put("flag", "Integer");
            put("datetime", "Date");
            put("dt", "Integer");
            put("m", "Integer");
            put("n", "Integer");
            put("a", "Double");
        }
    };
    private final Map<String, Object> warning = new HashMap<String, Object>() {
        {
            put("entId", "String");
            put("w1", "Double");
            put("fitness", "Double");
            put("datetime", "Date");
            put("last", "String");
        }
    };
    @Autowired SoundDao soundDao;

    @Override
    public long countByAcousticEmissionIntensity(String mineId, String deviceId, String startTime, String endTime,
        int timeSpan, String timeUnit) throws Throwable {
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "ACOUSTICEMISSIONINTENSITYREALTIME");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("deviceId", "\'" + deviceId + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        return soundDao.countByAcousticEmissionIntensity(parram);
    }

    @Override public List<Map<String, Object>> queryRealTimeByAcousticEmissionIntensity(String mineId, String deviceId,
        String startTime, String endTime, int timeSpan, String timeUnit, int page, int size, String startRow)
        throws Throwable {
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "ACOUSTICEMISSIONINTENSITYREALTIME");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("deviceId", "\'" + deviceId + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        //parram.put("size", size);

        List<Map<String, Object>> result = soundDao.queryRealTimeByAcousticEmissionIntensity(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }
        return result;
    }

    @Override public long countBySonicPulseRealTime(String mineId, String deviceId, String startTime, String endTime,
        int timeSpan, String timeUnit) throws Throwable {
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "sonicpulserealtime");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("deviceId", "\'" + deviceId + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        return soundDao.countByAcousticEmissionIntensity(parram);
    }

    @Override
    public List<Map<String, Object>> queryRealTimeBySonicPulseRealTime(String mineId, String deviceId, String startTime,
        String endTime, int timeSpan, String timeUnit, int page, int size, String startRow) throws Throwable {
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "sonicpulserealtime");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("deviceId", "\'" + deviceId + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        //parram.put("size", size);

        List<Map<String, Object>> result = soundDao.queryRealTimeByAcousticEmissionIntensity(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> queryCal(String mineId, String workingFace, String startTime, String endTime,
        int n, int m, int dt, int a) throws Throwable {
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "CalSoundEmission");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("workingFace", "\'" + workingFace + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        List<Map<String, Object>> result = soundDao.queryCal(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }

        return result;
    }

    @Override public List<Map<String, Object>> querydeviationLast(String mineId, String workingFace, String startTime,
        String endTime, int m, int dt, int n, double a) throws Throwable {

        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "CalSoundEmission");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("workingFace", "\'" + workingFace + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        List<Map<String, Object>> result = soundDao.queryCal(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }
        List<Map<String, Object>> newlist = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < result.size(); i++) {
            if (i % 3 == 0) {
                newlist.add(result.get(i));
            }
        }
        return SoundEmissionAlgorithm.devAbnormal(newlist, n / m, m);
    }

    @Override public List<Map<String, Object>> deviationLastTotal(String mineId, String workingFace, String startTime,
        String endTime, int m, int dt, int n, double a) throws Throwable {

        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "CalSoundEmission");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("workingFace", "\'" + workingFace + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        List<Map<String, Object>> result = soundDao.queryCal(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }
        List<Map<String, Object>> newlist = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < result.size(); i++) {
            if (i % 3 == 0) {
                newlist.add(result.get(i));
            }
        }
        return SoundEmissionAlgorithm.devAbnormalTotal(newlist, n / m, m);
    }

    @Override public List<Map<String, Object>> deviationFrequency(String mineId, String workingFace, String startTime,
        String endTime, int m, int dt, int n, double a) throws Throwable {

        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "CalSoundEmission");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("workingFace", "\'" + workingFace + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        List<Map<String, Object>> result = soundDao.queryCal(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }
        List<Map<String, Object>> newlist = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < result.size(); i++) {
            if (i % 3 == 0) {
                newlist.add(result.get(i));
            }
        }
        return SoundEmissionAlgorithm.devAbnormalFrequency(newlist, n / m);
    }

    /**
     * @Description: 综合预警
     * @Param: [mineId, startTime, endTime]
     * @return: java.util.Map<java.lang.String   ,   java.lang.Object>
     * @Author: ChengQi
     * @Date: 2019/1/8
     */
    @Override public Map<String, Object> comprehensiveWarning(String mineId, String startTime, String endTime)
        throws Throwable {
        String startRow = "";
        String endRow = "";

        startTime = DateUtils.getBeforeDayDate(-30, startTime, "yyyy-MM-dd HH:mm:ss");

        List<Map<String, Object>> conditions = new ArrayList<Map<String, Object>>();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("columnFamily", "warning");
        parram.put("columnId", "entId");
        parram.put("valueType", "String");
        parram.put("value", mineId);
        parram.put("symbol", "EQUAL");
        conditions.add(parram);
        parram = new HashMap<String, Object>();
        parram.put("columnFamily", "warning");
        parram.put("columnId", "datetime");
        parram.put("valueType", "Long");
        parram.put("value", DateUtils.fomatDateTime(startTime).getTime());
        parram.put("symbol", "GREATER_OR_EQUAL");
        conditions.add(parram);
        parram = new HashMap<String, Object>();
        parram.put("columnFamily", "warning");
        parram.put("columnId", "datetime");
        parram.put("valueType", "Long");
        parram.put("value", DateUtils.fomatDateTime(endTime).getTime());
        parram.put("symbol", "LESS_OR_EQUAL");
        conditions.add(parram);

        if (StringUtils.isNotBlank(startTime) && StringUtils.isBlank(startRow)) {
            endRow = String.valueOf(DateUtils.fomatDateTime(startTime).getTime());
        }
        if (StringUtils.isNotBlank(endTime)) {
            startRow = String.valueOf(DateUtils.fomatDateTime(endTime).getTime());
        }

        List<Map<String, Object>> result =
            HBaseDriver.queryData("CalWarningSoundEmission", conditions, -1, 100000, this.warning, startRow, endRow);

        double sumWi = 0.0;
        double sumRi = 0.0;
        double maxR = 0.0;
        double maxW = 0.0;
        for (int i = 0; i < result.size(); i++) {
            sumWi += Double.parseDouble(result.get(i).get("w1").toString());
            sumRi += Double.parseDouble(result.get(i).get("fitness").toString());
            maxR = maxR > Double.parseDouble(result.get(i).get("fitness").toString()) ?
                maxR :
                Double.parseDouble(result.get(i).get("fitness").toString());
            maxW = maxW > Double.parseDouble(result.get(i).get("w1").toString()) ?
                maxW :
                Double.parseDouble(result.get(i).get("w1").toString());
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("R", maxR);
        map.put("W", EigenvalueAlgorithm.divide(sumWi * maxR, sumRi * maxW, 0));
        map.put("result", result);
        return map;
    }
}
